'''
Created on Oct 21, 2012

@author: Artur
'''
import re

def ParseInstance(filename):
    data = []
    with open(filename, 'r') as f:
        for line in f:
            data.append(line.rstrip().split(':'))
    return data


def ParseSchema(filename, width):
    attrs = {}
    i = 0
    head_str = '{0:<{width}}'.format('TID', width=width)
    with open(filename, 'r') as f:
        for line in f:
            attr = line.split()[0]
            attrs[attr] = i
            i += 1
            head_str += '{0:<{width}}'.format(attr, width=width)
    return (attrs, head_str)


def ParseFds(filename, attrs):
    fds = []
    with open(filename, 'r') as f:
        for line in f:
            (lhs, rhs) = re.sub('[ \n]', '', line).split("->")
            lhs = tuple([attrs[x] for x in lhs.split(',')])
            rhs = attrs[rhs]
            fds.append((lhs, rhs))
    return fds


def ParseBlockLine(line):
    (bid, cells) = line.replace(' ', '').split(':')
    cells = cells.split('],')[:-1]
    cell_list = []
    for cell in cells:
        cell_list.append(tuple([int(x) for x in (cell.replace('[','').split(','))]))
    return (int(bid), cell_list)


def ParseBlockMap(filename):
    block_map = {}
    with open(filename, 'r') as f:
        for line in f:
            (bid, cell_list) = ParseBlockLine(line)
            block_map[bid] = cell_list
    return block_map


def ParseBlockAndCellMap(filename):
    block_map = {}
    cell_map = {}
    done_blocks = False
    with open(filename, 'r') as f:
        for line in f:
            if line == '\n':
                done_blocks = True
            else:
                # parse block map
                if not done_blocks:
                    (bid, cell_list) = ParseBlockLine(line)
                    block_map[bid] = cell_list
                # parse cell map
                else:
                    (cell, bid) = re.sub('[\[\] ]', '', line).split(':')
                    cell_map[tuple([int(x) for x in cell.split(',')])] = int(bid)
    return (block_map, cell_map)
                

def PrintoutBlockMap(block_map, filename, data, width, head_str, nattrs):
    with open(filename, 'w') as f:
        
        f.write('Total {} blocks\n\n'.format(len(block_map)))
        
        for bid in block_map.keys():
        
            f.write('{0:*^{width}}\n\n'.format('Block {}'.format(bid), width=width*nattrs))
            f.write(head_str + '\n')
            
            cells = block_map[bid]
            tmap = {}
            for cell in cells:
                tid = cell[0]
                if tid in tmap:
                    tmap[tid].append(cell[1])
                else:
                    tmap[tid] = [cell[1]]
            
            for tid in sorted(tmap.keys()):
                out_str = '{0:<{width}}'.format(tid, width=width)
                for a in range(0, nattrs):
                    if a in tmap[tid]:
                        out_str += '{0:<{width}}'.format(data[tid][a], width=width)
                    else:
                        out_str += '{0:<{width}}'.format('', width=width)
                f.write(out_str + '\n')
        
            f.write('\n{0:*^{width}}\n\n'.format('', width=width*nattrs))